(function ($) {
	var me = {};
	var Grid = function(element, options) {
		this.element = $(element);
		me = this;
		$.each(options,function(k,v){
			if( v == undefined && v == null ) return true;
			if( typeof v === 'object' ) {
				if( k == 'dataTablesOption' ) {
					me[k] = $.extend({}, me[k]);
					$.each(options[k],function(key,val){
						if( key == 'columns' ) {
							me[k][key] = $.extend([], val);
						} else {
							me[k][key] = $.extend({},me[k][key], val);
						}
					});
				} else {
					$.extend(me.get(k),v);
				}
			} else {
				me.set(k,v);
			}
		});
		// 设置配置
		if( me.searchFormId == '' )
			me.set('searchFormId',me.prefixId + "Search");
		// 设置配置
		if( me.uploadFormId == '' )
			me.set('uploadFormId',me.prefixId + "Upload");
	};
	// 默认配置
	Grid.prototype = {
		constructor: Grid,
		// 设置
		set: function(key,val){
			this[key] = val;
			return this;
		},
		// 获取
		get: function(key){
			return this[key];
		},
		// 是否自动加载
		autoLoad: true,
		// 主键字段
		pkField: "id",
		// ID前缀 - 必填
		prefixId: "",
		// 是否为树形结构
		isTreeGrid : 0,
		// 上传表单ID
		uploadFormId: "",
		// 查询表单ID
		searchFormId: "",
		// 选中行索引
		selectIndexes: {},
		// 搜索表单元素配置
		searchOption: [],
		// 搜索表单元素模板
		searchElementTpl: '<label class="inline">' +
						'<span class="lbl">{0}：</span>' +
						'{1}' +
					'</label>',
		// 创建搜索表单元素
		createSearchElement: function(){
			var formElementSettings = {
				elementOption: me.searchOption,
				elementTpl: me.searchElementTpl
			};
			$('#' + me.searchFormId).formElement(formElementSettings);
		},
		// 按钮列表
		buttons: ['add','edit','delete','remove','print','search','reset','export','import'],
		// 按钮背景div元素
		buttonBackdrop: '<div class="wizard-actions">' +
							'{0}' +
						'</div>',
		// 搜索按钮div元素
		buttonTpl: '<a class="{3}" title="{2}" id="{0}" href="javascript:;">' +
						'<i class="ace-icon fa {1}"></i>{2}' +
					'</a>',
		// 新增按钮
		addButton: {
			enable: true,
			id: "btnAdd",
			title: '新增',
			icon: "fa-plus",
			className: "btn btn-primary btn-sm",
			url: "",
			buttonTpl: "",
			afterAction: function(){},
		},
		// 新增操作
		addAction: function(){
			var hash = '#page' + me.editButton.url;
			changeAjaxContent(hash);
		},
		// 修改按钮
		editButton: {
			enable: true,
			id: "btnEdit",
			title: '修改',
			icon: "fa-pencil",
			className: "btn btn-primary btn-sm",
			url: "",
			buttonTpl: "",
			afterAction: function(){},
		},
		// 修改操作
		editAction: function(){
			var indexes = me.selectIndexes;
			var indexData = indexes[Object.keys(indexes)[Object.keys(indexes).length-1]];
			if( indexData == undefined ) {
				me.showMsg("请先选择行！");
				return;
			}
			var hash = '#page' + me.editButton.url + '?' + me.pkField + '=' + indexData[me.pkField];
			changeAjaxContent(hash);
		},
		// 永久删除按钮
		deleteButton: {
			enable: true,
			id: "btnDelete",
			title: '删除',
			icon: "fa-trash-o",
			className: "btn btn-primary btn-sm",
			url: "",
			buttonTpl: "",
			afterAction: function(){},
		},
		// 永久删除操作
		deleteAction: function(){
			var rows = me.objGrid.rows({selected: true}), datas = rows.data(), params = [];
			for( var i = 0; i < datas.length; i++ ){
				params.push(datas[i][me.pkField]);
			}
			if( params.length == 0 ) {
				me.showMsg("请先选择行！");
				return;
			}
			var dialogBtn = {
				success: {
					label: "确定",
					className: "btn-sm btn-primary",
					callback: function(){
						$.ajax({
							type: "get",
							dataType: "json",
							url: me.deleteButton.url,
							data: me.pkField + "=" + params,
							success: function(data){
								me.showMsg(data.msg);
								me.objGrid.ajax.reload();
							},
							error: function(data){}
						});
					}
				},
				cancel: "cancel"
			};
			me.showMsg('确定删除吗？',dialogBtn);
		},
		// 物理删除按钮
		removeButton: {
			enable: false,
			id: "btnRemove",
			title: '删除',
			icon: "fa-times",
			className: "btn btn-primary btn-sm",
			url: "",
			buttonTpl: "",
			afterAction: function(){},
		},
		// 物理删除操作
		removeAction: function(){
			var rows = me.objGrid.rows({selected: true}), datas = rows.data(), params = [];
			for( var i = 0; i < datas.length; i++ ){
				params.push(datas[i][me.pkField]);
			}
			if( params.length == 0 ) {
				me.showMsg("请先选择行！");
				return;
			}
			var dialogBtn = {
				success: {
					label: "确定",
					className: "btn-sm btn-primary",
					callback: function(){
						$.ajax({
							type: "get",
							dataType: "json",
							url: me.removeButton.url,
							data: me.pkField + "=" + params,
							success: function(data){
								me.showMsg(data.msg);
								me.objGrid.ajax.reload();
							},
							error: function(data){}
						});
					}
				},
				cancel: "cancel"
			};
			me.showMsg('确定删除吗？',dialogBtn);
		},
		// 导出按钮
		exportButton: {
			enable: false,
			id: "btnExport",
			title: '导出',
			icon: "fa-database",
			className: "btn btn-primary btn-sm",
			url: "",
			buttonTpl: "",
			afterAction: function(){},
		},
		// 导出操作
		exportAction: function(){
			window.open(me.exportButton.url);
		},
		// 导入按钮
		importButton: {
			enable: false,
			id: "btnImport",
			title: '导入',
			icon: "fa-upload",
			className: "btn btn-primary btn-sm",
			fieldName: "file",
			url: "",
			buttonTpl: '<div class="col-xs-3">' +
							'<form id="{4}" method="post" enctype ="multipart/form-data">' +
								'<input type="file" name="{5}" />' +
							'</form>' +
							'<a class="{3}" title="{2}" id="{0}" href="javascript:;">' +
								'<i class="ace-icon fa {1}"></i>{2}' +
							'</a>' +
						'</div>',
			afterAction: function(){
				var formId = me.uploadFormId, $form = $("#" + formId);
				$form.find('input[type=file]').ace_file_input({
					//style : 'well',
					no_file:'',
					btn_choose:'请选择',
					btn_change:'重新选择',
					droppable:false,
					onchange:null,
					thumbnail:false //| true | large
					//maxSize: 110000,//bytes
					//allowExt: ["jpeg", "jpg", "png", "gif"],
					//denyExt:[],
					//allowMime: ["image/jpg", "image/jpeg", "image/png", "image/gif"],
					//denyMime:[],
					//
				});
			},
		},
		// 导入操作
		importAction: function(){
			var formId = me.uploadFormId, $form = $("#" + formId);
			var formData = new FormData($form[0]);
			$.ajax({
				type: "post",
				dataType: "json",
				url: me.importButton.url,
				data: formData,
				async: false,
				cache: false,
				contentType: false,
				processData: false,
				success: function(data){
					var dialogBtn = {};
					if( data.isOk == 0 ) {
						dialogBtn = {
							success: {
								label: "确定",
								className: "btn-sm btn-primary",
								callback: function(){
									window.open(data.result.errorUrl);
								}
							},
							cancel: "cancel"
						};
					}
					me.showMsg(data.msg,dialogBtn);
					me.objGrid.ajax.reload();
				},
				error: function(data){}
			});
		},
		// 打印按钮
		printButton: {
			enable: false,
			id: "btnPrint",
			title: '打印',
			icon: "fa-print",
			className: "btn btn-primary btn-sm",
			buttonTpl: "",
			afterAction: function(){},
		},
		// 打印操作
		printAction: function(){
		},
		// 查询按钮
		searchButton: {
			enable: true,
			id: "btnSearch",
			title: '查询',
			icon: "fa-search",
			className: "btn btn-primary btn-sm",
			buttonTpl: "",
			afterAction: function(){},
		},
		// 查询操作
		searchAction: function(){
			var formId = me.searchFormId, $form = $("#" + formId);
			// 保存搜索条件
			$form.data( "#" + formId, JSON.stringify($form.serializeArray()) );
			me.objGrid.ajax.reload();
		},
		// 重置按钮
		resetButton: {
			enable: true,
			id: "btnReset",
			title: '重置',
			icon: "fa-undo",
			className: "btn btn-primary btn-sm",
			buttonTpl: "",
			afterAction: function(){},
		},
		// 重置操作
		resetAction: function(){
			var formId = me.searchFormId, $form = $("#" + formId);
			$form[0].reset();
			// 清楚缓存中的搜索条件
			$form.data("#" + formId, '');
			me.objGrid.ajax.reload();
		},
		// 创建搜索按钮
		createSearchButtons: function(){
			var html = '', $form = $("#" + me.searchFormId);
			var btnDiv = $form.next('.wizard-actions').length;
			$.each(me.buttons,function(k,v){
				var val = me[v + 'Button'];
				// 未启用则退出本次循环
				if( !val['enable'] ) return true;
				var _id = val.id || "", _icon = val.icon || "", _title = val.title || "", _className = val.className || "";
				if( v == 'import' ) {
					html += val.buttonTpl.format(_id,_icon,_title,_className,me.uploadFormId,val.fieldName);
					html += '&nbsp; ';
				} else {
					html += val.buttonTpl != "" ? val.buttonTpl.format(_id,_icon,_title,_className) : me.buttonTpl.format(_id,_icon,_title,_className);
					html += '&nbsp; ';
				}
			});
			if( btnDiv > 0 ) {
				$form.next('.wizard-actions').append(html);
			} else {
				html = me.buttonBackdrop.format(html);
				$form.after(html);
			}
			// 绑定操作事件
			$.each(me.buttons,function(k,v){
				var val = me[v + 'Button'];
				if( !val['enable'] ) return true;
				val.afterAction();
				var _event = me[v + 'Action'] || function(){};
				$("#" + val.id).on('click', function(){
					_event();
				});
			});
		},
		showMsg: function(msg,buttons){
			var buttons = buttons || ['success'];
			var btnConfig = {
				success: {
					label: "确定",
					className: "btn-sm btn-primary",
					callback: function(){
						//me.objGrid.ajax.reload();
					}
				},
				cancel: {
					label: "取消",
					className: "btn-sm",
				}
			};
			var dialogOption = {
				message: msg,
				buttons: {}
			};
			$.each(buttons,function(key,val){
				if( typeof val == 'object' ) {
					dialogOption.buttons[val] = val;
				} else if( typeof val == 'string' ) {
					dialogOption.buttons[val] = btnConfig[val];
				}
			});
			bootbox.dialog(dialogOption);
		},
		// 多选格式
		selectMultiCheckbox: {
			// 设置列的数据源，即如何从整个Table的数据源(object / array)中获得
			data: "id",
			// 设置列的标题
			title: '<label class="pos-rel">' +
						'<input type="checkbox" value="" class="ace" />' +
						'<span class="lbl"></span>' +
					'</label>',
			// 给列中每个单元格指定一个或多个class
			className: "center",
			// 开启/禁用这列是否排序
			orderable: false,
			// 按第一列和第二列排序作为默认排序
			orderData: [ 0, 1 ],
			// 按第一次降序，第二次升序，第三次升序，依次循环
			orderSequence: [ "desc", "asc", "asc" ],
			// 数据处理
			render: function ( data, type, row, meta ) {
				return '<label class="pos-rel">' +
							'<input type="checkbox" value="' + data + '" class="ace" />' +
							'<span class="lbl"></span>' +
						'</label>';
			}
		},
		// 树形格式
		treeGridControl: {
			data: "id",
			title: '',
			className: "treegrid-control",
			render: function ( data, type, row, meta ) {
				if (row.children) {
					return '<i class="ace-icon fa glyphicon-plus"></i>';
				}
				return '';
			}
		},
		// dataTables配置
		dataTablesOption: {
			/* 定义组件元素的显示
				`l` 代表 length，左上角的改变每页显示条数控件
				`f` 代表 filtering，右上角的过滤搜索框控件
				`t` 代表 table，表格本身
				`i` 代表 info，左下角的表格信息显示控件
				`p` 代表 pagination，右下角的分页控件
				`r` 代表 processing，表格中间的数据加载等待提示框控件
				`B` 代表 button，Datatables可以提供的按钮控件，默认显示在左上角
			 */
			dom: 'ftip',
			// 是否允许Datatables开启本地搜索
			searching:false,
			// 是否允许排序
			ordering: true,
			// 设置默认排序
			order: [[ 1, 'desc' ]],
			// 是否开启服务器模式
			serverSide: true,
			// 每页显示多少条数据
			pageLength: 10,
			// tree配置
			'treeGrid': {
				'left': 10,
				'expandIcon': '<i class="ace-icon fa glyphicon-plus"></i>',
				'collapseIcon': '<i class="ace-icon fa glyphicon-minus"></i>'
			},
			// 语言配置选项
			language: {
				// 从远程获取语言信息
				url: "/resources/assets/data/grid-cn.json",
			},
			// 数据获取
			ajax: {
				// 请求地址
				url: "/resources/assets/data/grid.json",
				// 数据属性或操作表数据的方法
				dataSrc: "result"
			},
			serverParams: function (aoData) {
				$.each(me.searchOption,function(k,v){
					var value = $('#'+v.id).val();
					if( value != '' ) aoData[v.id] = value;
				});
				//aoData._rand = Math.random();
			},
			// 设置定义列的初始属性
			columns: [
				{
					// 为一个或多个列编制定义，0为第一列，-1为最好一列
					targets: 0,
					// 设置列的数据源，即如何从整个Table的数据源(object / array)中获得
					data: "id",
					// 设置列的标题
					title: '<label class="pos-rel">' +
								'<input type="checkbox" value="" class="ace" />' +
								'<span class="lbl"></span>' +
							'</label>',
					// 给列中每个单元格指定一个或多个class
					className: "center",
					// 开启/禁用这列是否排序
					orderable: false,
					// 按第一列和第二列排序作为默认排序
					orderData: [ 0, 1 ],
					// 按第一次降序，第二次升序，第三次升序，依次循环
					orderSequence: [ "desc", "asc", "asc" ],
					// 数据处理
					render: function ( data, type, row, meta ) {
						return '<label class="pos-rel">' +
									'<input type="checkbox" value="' + data + '" class="ace" />' +
									'<span class="lbl"></span>' +
								'</label>';
					}
				},{
					targets: -1,
					data: "id",
					title: "",
					orderable: false,
					render: function ( data, type, row, meta ) {
						return '<div class="btn-group dropup">' +
									'<button data-toggle="dropdown" class="btn btn-primary btn-white dropdown-toggle">' +
										'操作' +
										'<i class="ace-icon fa fa-angle-down icon-on-right"></i>' +
									'</button>' +
									'<ul class="dropdown-menu dropdown-info dropdown-menu-right">' +
										'<li>' +
											'<a class="blue" data-url="page/form-elements" href="#page/form-elements" >' +
												'<i class="ace-icon fa fa-search-plus bigger-130"></i>' +
												'查看明细' +
											'</a>' +
										'</li>' +
									'</ul>' +
								'</div>';
					}
				}
			],
			select: {
				// 选择方式，单行：single，多行：multi
				style: 'single',
				// 允许选择除最后一列以外的所有列
				//selector: 'td:first-child',
			},
        
        },
		// 显示列表
		showGrid: function(options){
			// 多选情况下，增加第一列多选框
			if( me.dataTablesOption.select.style == 'multi' && ( options.columns[0].render == undefined || options.columns[0].render.indexOf('checkbox') == -1 ) ) {
				var selectMultiCheckbox = me.selectMultiCheckbox;
				selectMultiCheckbox.data = me.pkField;
				options.columns.unshift(selectMultiCheckbox);
			}
			// 树形结构情况下，增加一列下拉按钮
			if( me.isTreeGrid == 1 ) {
				var treeGridControl = me.treeGridControl;
				treeGridControl.data = me.pkField;
				options.columns.unshift(treeGridControl);
			}
			// 渲染列表
			me.objGrid = me.element.DataTable(options);
			// 防止点击冲突
			me.objGrid.on('click', function(e) {
				e.stopImmediatePropagation();
				e.stopPropagation();
				e.preventDefault();
			});
			me.objGrid.on('draw', function(){
				$('.dropdown-toggle', this).dropdown();
			});
			// 选择
			me.objGrid.on( 'select', function ( e, dt, type, index ) {
				if ( type === 'row' ) {
					me.onClickRow('select', me.objGrid.row(index).index(), me.objGrid.row(index).data());
				}
			});
			// 取消选择
			me.objGrid.on( 'deselect', function ( e, dt, type, index ) {
				if ( type === 'row' ) {
					me.onClickRow('deselect', me.objGrid.row(index).index(), me.objGrid.row(index).data());
				}
			});
			// 点击复选框
			me.onClickbox();
		},
		// 点击行之前操作
		onClickRowBefor: function(type, rowIndex, rowData){},
		// 点击行之后操作
		onClickRowAfter: function(type, rowIndex, rowData){},
		// 点击行
		onClickRow: function(type, rowIndex, rowData){
			me.onClickRowBefor(type, rowIndex, rowData);
			var checked = false, indexes = me.selectIndexes;
			if( type == 'select' ) {
				checked = true;
				indexes['key'+rowIndex] = rowData;
			} else if( type == 'deselect' ) {
				checked = false;
				delete indexes['key'+rowIndex];
			}
			// 选中/取消行 - 则选中/取消复选框
			$(  me.objGrid.row(rowIndex).node() ).find('input:checkbox').prop('checked', checked);
			me.onClickRowAfter(type, rowIndex, rowData);
		},
		// 点击行复选框之前操作
		onClickboxBefor: function(rowIndex, rowData){},
		// 点击行复选框之后操作
		onClickboxAfter: function(rowIndex, rowData){},
		// 点击行复选框
		onClickbox: function(){
			var table = me.objGrid;
			// 选中头部checkbox则选中所有行
			me.element.on('click', 'th input[type=checkbox]' , function(){
				if( me.dataTablesOption.select.style == 'single' ) return true;
				var th_checked = this.checked;
				if( th_checked ) {
					me.element.find('td input[type=checkbox]').prop('checked', true);
					table.rows().select();
				} else {
					me.element.find('td input[type=checkbox]').prop('checked', false);
					table.rows().deselect();
				}
			});
			// 选中checkbox则选中整行
			me.element.on('click', 'td input[type=checkbox]' , function(){
				var _row = $(this).closest('tr'), row = _row.get(0), index = _row.index();
				me.onClickboxBefor(index, table.row(row).data());
				// 单选情况下其他行取消选中
				if( me.dataTablesOption.select.style == 'single' ) {
					me.element.find('th input[type=checkbox]').prop('checked', false);
					me.element.find('td input[type=checkbox]:checked').each(function(){
						if( $(this).closest('tr').index() != index ) $(this).prop('checked', false);
					});
					table.rows().deselect();
				}
				// 选中该行
				if( this.checked ) {
					table.row(row).select();
				} else {
					table.row(row).deselect();
				}
				me.onClickboxAfter(index, table.row(row).data());
			});
		},
		// 创建Element
		load: function(option){
			me.beforeLoad();
			me.createSearchElement();
			me.createSearchButtons();
			me.showGrid(option);
			me.afterLoad();
		},
		// 加载数据前操作
		beforeLoad: function(){},
		// 加载数据之后操作
		afterLoad: function(){},
    };
    /**
     * 扩展 Jquery 对象为 Grid
     * @param option
     */
	$.fn.grid = function(option){
		return this.each(function () {
			var $this = $(this),
				data = $this.data('grid'),
				options = typeof option === 'object' && option;
			if (!data)  {
				$this.data('grid', (data = new Grid(this, $.extend({}, options))));
			}
			if (typeof option == 'string') {
				data[option]();
			}
			if(data.autoLoad){
				data.load(data.dataTablesOption);
			}
		});
	};
	// 属性返回对创建此对象的函数的引用
	$.fn.grid.Constructor = Grid;

})(jQuery);


